Skip to content

使用 Docker Compose 架設與配置 Nginx

TLDR

  • Nginx 設定檔由 Main、Events、HTTP 等 Context 組成,建議將自定義設定放在 /etc/nginx/conf.d/ 目錄下。
  • location 匹配優先級:精確匹配 (=) > 前綴強匹配 (^~) > 正規表示式 (~, ~*) > 普通前綴匹配 > 通用匹配 (/)。
  • proxy_pass 若包含路徑(如 /),會替換掉 location 匹配的路徑部分;若不包含路徑,則完整轉發。
  • map 指令應集中於單一檔案(如 maps.conf),避免因檔名排序導致重複定義被覆蓋。
  • 使用 Docker 掛載設定檔時,建議加上 :ro(唯讀)屬性,保護設定檔不被容器內程序意外修改。
  • 變更設定後,務必先執行 nginx -t 檢查語法,再執行 nginx -s reload 重新載入。
  • 若需使用環境變數動態配置 Nginx,可使用官方提供的 .template 功能,但需注意此方式需重啟容器方能生效。

Nginx 設定架構與匹配邏輯

Nginx 設定檔結構由外至內分為 Main、Events 與 HTTP Context。在 http 區塊中,透過 server 定義虛擬主機,並利用 location 處理路徑匹配。

Location 匹配優先級

什麼情況下會遇到這個問題:當需要精確控制不同 URL 路徑的處理邏輯時。

匹配規則優先級如下:

  1. 精確匹配 =:完全相同才匹配。
  2. 前綴強匹配 ^~:匹配成功後停止搜尋正規表示式。
  3. 正規表示式 ~(區分大小寫)與 ~*(不區分大小寫):按定義順序執行。
  4. 普通前綴匹配:最長匹配優先。
  5. 通用匹配 /:預設規則。

WARNING

若同時定義 location /testlocation ^~ /test,Nginx 會因規則衝突報錯。

Proxy Pass 與路徑處理

什麼情況下會遇到這個問題:當反向代理轉發路徑不符合預期時。

  • 無路徑轉發proxy_pass http://backend,完整原始 URI 會被傳遞。
  • 有路徑轉發proxy_pass http://backend/location 匹配的部分會被替換。

設定檔管理與最佳實踐

檔案組織建議

Nginx 預設會載入 /etc/nginx/conf.d/*.conf。由於 Nginx 依檔名字母順序載入,且重複定義的 map 變數會以後載入者為準,建議將 map 定義集中於 maps.conf,避免命名空間衝突。

Docker 掛載與唯讀權限

什麼情況下會遇到這個問題:當需要確保設定檔不被容器內程序竄改時。

compose.yaml 中掛載設定檔時,建議加上 :ro

yaml
volumes:
  - ./volumes/config/conf.d:/etc/nginx/conf.d:ro

這能防止容器啟動時自動修改設定檔(例如自動補上 IPv6 監聽),但需注意 log 目錄或快取目錄不可設為 :ro,否則會導致寫入失敗。


實作與驗證

靜態網站與反向代理

使用 Docker Compose 部署時,應將設定檔、網站內容與 log 分離掛載。

驗證指令:

bash
# 測試設定檔語法
docker compose exec nginx nginx -t

# 重新載入設定檔(不中斷服務)
docker compose exec nginx nginx -s reload

使用 Template 動態配置

什麼情況下會遇到這個問題:當需要透過環境變數動態調整 Nginx 設定時。

將設定檔命名為 default.conf.template,並在 compose.yaml 中掛載至 /etc/nginx/templates

  • 優點:可直接在 environment 區塊注入變數。
  • 缺點:變數替換僅在容器啟動時執行,修改環境變數後必須重啟容器,無法透過 nginx -s reload 生效。

異動歷程

    • 初版文件建立。